#1-1 打印Tensorflow版本
import tensorflow as tf
from tensorflow import keras

import numpy as np
import matplotlib.pyplot as plt

class_names=['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat',
               'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']
print(tf.__version__)

#1.导入数据集
fashion_mnist = keras.datasets.fashion_mnist
(train_images, train_labels),(test_images, test_labels) = fashion_mnist.load_data()

#2 预处理数据（像素值，如上图所示可以看到像素值处于0到255之间）
train_images = train_images/255.0
test_images = test_images/255.0

#2-1 显示训练集中的前25个图像
plt.figure(figsize=(10, 10))
for i in range(25):
    plt.subplot(5, 5, i+1)  #（行，列，序列值）
    plt.xticks([])  #设置坐标轴
    plt.yticks([])
    plt.grid(False)  #设置不显示网格线
    plt.imshow(train_images[i], cmap=plt.cm.binary)
    plt.xlabel(class_names[train_labels[i]])
plt.show()

#3.设置模型内容（层）
model = keras.Sequential([
  keras.layers.Flatten(input_shape=(28, 28)),
  keras.layers.Dense(128, activation='relu'),
  keras.layers.Dense(10),
  keras.layers.Softmax()  #把原网址后面添加的softmax层提前添加在了模型里
])

#4.设置模型损失函数、优化器、指标
model.compile(optimizer='adam',
       loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
       metrics=['accuracy'])

#5.训练模型
#调用model.fit方法，该方法将模型和数据进行“拟合”
model.fit(train_images, train_labels, epochs=40)

#6-1评估准确率
test_loss, test_acc = model.evaluate(test_images, test_labels, verbose=2)
print('\nTest accuracy:', test_acc)

#plus2:通过将图片的类别概率绘制成图表，看看模型对于全部10个类的预测

#绘制图片
def plot_image(i, predictions_array, true_label, img):
    predictions_array, true_label, img = predictions_array, true_label[i], img[i]
    plt.grid(False)  #不绘制网格
    plt.xticks([])  #设置x坐标轴为空
    plt.yticks([])  #设置y坐标轴为空

    plt.imshow(img, cmap=plt.cm.binary)  #展示图片

    predicted_label = np.argmax(predictions_array)
    if predicted_label == true_label:
        color = 'blue'
    else:
        color = 'red'

    #三个值：预测类别名称、概率值、真实类别名称
    plt.xlabel("{} {:2.0f}% ({})".format(class_names[predicted_label],
                                100*np.max(predictions_array),
                                class_names[true_label]),
                                color=color)

#绘制图片类别概率的展示图
def plot_value_array(i, predictions_array, true_label):
    predictions_array, true_label = predictions_array, true_label[i]
    plt.grid(False)  #设置没有网格线
    plt.xticks(range(10))  # 设置x坐标轴值为0-9
    plt.yticks([])  # 设置y坐标轴值为空
    thisplot = plt.bar(range(10), predictions_array, color="#777777")  # plt.bar(x,height,width,color)
    plt.ylim([0, 1])  # 设置y轴坐标值范围
    predicted_label = np.argmax(predictions_array)

    thisplot[predicted_label].set_color('red')  # 设置预测标签为红色
    thisplot[true_label].set_color('blue')  # 设置真实标签值为蓝色

num_rows = 5
num_cols = 3
num_images = num_rows*num_cols
plt.figure(figsize=(2*2*num_cols,2*num_rows))
for i in range(num_images):
    plt.subplot(num_rows, num_cols*2, 2*i+1)
    predictions = model.predict(test_images)
    plot_image(i, predictions[i], test_labels, test_images)
    plt.subplot(num_rows, num_cols*2, 2*i+2)
    plot_value_array(i, predictions[i], test_labels)
plt.tight_layout()
plt.show()

